package com.grpc_client;
/*

                  写字楼里写字间，写字间里程序员；
                  程序人'猿'写程序，又拿程序换酒钱。
                  酒醒只在网上坐，酒醉还来网下眠；
                  酒醉酒醒日复日，网上网下年复年。
                  但愿老死电脑间，不愿鞠躬老板前；
                  奔驰宝马贵者趣，公交自行程序员。
                  别人笑我忒疯癫，我笑自己命太贱；
                  不见满街漂亮妹，哪个归得程序'猿'？
━━━━━━神兽出没━━━━━━
 ┏┓   ┏┓
┏┛┻━━━┛┻┓
┃       ┃
┃   ━   ┃
┃ ┳┛ ┗┳ ┃
┃       ┃
┃   ┻   ┃
┃       ┃
┗━┓   ┏━┛
  ┃   ┃                    神兽保佑, 永无BUG!
  ┃   ┃       Code is far away from bug with the animal protecting
  ┃   ┗━━━┓
  ┃       ┣┓
  ┃       ┏┛
  ┗┓┓┏━┳┓┏┛
   ┃┫┫ ┃┫┫
   ┗┻┛ ┗┻┛
 */

import com.HelloWorldClient;
import io.grpc.ClientInterceptor;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.inprocess.InProcessChannelBuilder;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.okhttp.OkHttpChannelBuilder;
import io.netty.util.internal.PlatformDependent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Created by 石头哥哥 on 1/13/16.
 * <p>
 * grpc
 * <p>
 * com.grpc_client
 * <p>
 * comments:
 */
public class GrpcClient {


    private final Logger logger = LoggerFactory.getLogger(HelloWorldClient.class);

    /**
     * create a singleton
     */
    private ManagedChannel channel;


    /**
     * @param host
     * @param port
     */
    public GrpcClient(String host, int port) {

        // TODO: 1/13/16 当前android平台okhttp采用 2.4.0版本 
        if (PlatformDependent.isAndroid()) {// android  平台
            channel = OkHttpChannelBuilder.forAddress(host, port)
                    .usePlaintext(true)
                    .build();
        } else {
            ManagedChannelBuilder managedChannelBuilder = ManagedChannelBuilder.forAddress(host, port);
            if (managedChannelBuilder instanceof NettyChannelBuilder) {
                NettyChannelBuilder nettyChannelBuilder = (NettyChannelBuilder) managedChannelBuilder;

                //default is TLS
//            nettyChannelBuilder.negotiationType(NegotiationType.TLS);
//            try {
//                nettyChannelBuilder.sslContext(GrpcSslContexts.forClient().build());
//            } catch (SSLException e) {
//                e.printStackTrace();
//            }

                channel = nettyChannelBuilder
                        .usePlaintext(true)
                        .build();

            } else if (managedChannelBuilder instanceof InProcessChannelBuilder) {

                InProcessChannelBuilder inProcessChannelBuilder =
                        (InProcessChannelBuilder) managedChannelBuilder;
                channel = inProcessChannelBuilder
                        .usePlaintext(true)
                        .build();
            }

        }


    }


    /**
     * @param host
     * @param port
     * @param interceptors 异步回调
     */
    public GrpcClient(String host, int port, List<ClientInterceptor> interceptors) {
        ManagedChannelBuilder managedChannelBuilder = ManagedChannelBuilder.forAddress(host, port);

        if (managedChannelBuilder instanceof NettyChannelBuilder) {
            NettyChannelBuilder nettyChannelBuilder = (NettyChannelBuilder) managedChannelBuilder;

            //default is TLS
//            nettyChannelBuilder.negotiationType(NegotiationType.TLS);
//            nettyChannelBuilder.sslContext(GrpcSslContexts.forClient().build());

            channel = nettyChannelBuilder
                    .usePlaintext(true)
                    .intercept(interceptors)
                    .build();

        } else if (managedChannelBuilder instanceof InProcessChannelBuilder) {

            InProcessChannelBuilder inProcessChannelBuilder =
                    (InProcessChannelBuilder) managedChannelBuilder;
            channel = inProcessChannelBuilder
                    .usePlaintext(true)
                    .intercept(interceptors)
                    .build();
        }
    }


    /**
     * get channel
     *
     * @return
     */

    public ManagedChannel getChannel() {
        return channel;
    }


    /**
     * release client resource
     *
     * @throws InterruptedException
     */
    public void shutdown() throws InterruptedException {
        channel.shutdown().awaitTermination(0, TimeUnit.SECONDS);
    }
}
